#include <iostream>
#include <string>
#include <vector>

//电脑组装：显示器、鼠标、键盘、主机(主机又包括CPU、显卡、主板等)
//1.找到店铺老板告诉需求
//2.客服安排技术人员组装
//3.产品组装完成

class AbstractProduct {
public:
    virtual void setDisplayer(std::string displayer) = 0;
    virtual void setMouse(std::string mouse) = 0;
    virtual void setKeyboard(std::string keyboard) = 0;
    virtual void setHost(std::string host) = 0;
    virtual void show() = 0;
};

class Computer : public AbstractProduct {
public:
    void setDisplayer(std::string displayer) override {
        m_displayer = displayer;
    }
    void setMouse(std::string mouse) override {
        m_mouse = mouse;
    }
    void setKeyboard(std::string keyboard) override {
        m_keyboard = keyboard;
    }

    void setHost(std::string host) override {
        m_host = host;
    }

    void show() override {
        std::cout << "displayer:" << m_displayer << std::endl;
        std::cout << "mouse:" << m_mouse << std::endl;
        std::cout << "keyboard:" << m_keyboard << std::endl;
        std::cout << "host:" << m_host << std::endl;
    }

private:
    std::string m_displayer;
    std::string m_mouse;
    std::string m_keyboard;
    std::string m_host;
};

class AbstractBuilder {
public:
    AbstractBuilder() : product(new Computer) {}
    virtual void buildDisplayer(std::string displayer) = 0;
    virtual void buildMouse(std::string mouse) = 0;
    virtual void buildKeyboard(std::string keyboard) = 0;
    virtual void buildHost(std::string host) = 0;
    AbstractProduct* getProduct() {
        return product;
    }

protected:
    AbstractProduct* product;

};

class ComputerBuilder : public AbstractBuilder { 
public:
    void buildDisplayer(std::string displayer) override {
        product->setDisplayer(displayer);
    }
    void buildMouse(std::string mouse) override {
        product->setMouse(mouse);
    }
    void buildKeyboard(std::string keyboard) override {
        product->setKeyboard(keyboard);
    }
    void buildHost(std::string host) override {
        product->setHost(host);
    }
};

class Director {
public:
    Director(AbstractBuilder* builder) : m_builder(builder) {}
    void construct() {
        m_builder->buildDisplayer("dell");
        m_builder->buildMouse("logitech");
        m_builder->buildKeyboard("logitech");
        m_builder->buildHost("intel");
    }

    AbstractProduct* construct(std::string displayer, std::string mouse, std::string keyboard, std::string host) {
        m_builder->buildDisplayer(displayer);
        m_builder->buildMouse(mouse);
        m_builder->buildKeyboard(keyboard);
        m_builder->buildHost(host);
        return m_builder->getProduct();
    }

private:
    AbstractBuilder* m_builder;
};

int main(int argc, char const *argv[]) {
    Director* director = new Director(new ComputerBuilder);
    AbstractProduct* product = director->construct("dell", "logitech", "logitech", "intel");
    product->show();
    return 0;
}